child_process 是 Node.js 的一个核心模块,可以用于创建子进程,
因此虽然 js 是单线程的,但通过创建子进程也能实现多任务并行处理,也可通过其调用系统的功能指令完成复杂的任务。
主要提供了 4 个方法:spawn
、exec
、execFile
和 fork
。
下面逐一介绍各个方法的用法和作用。
支持 同步(spawnSync)
和 异步(spawn)
2 种调用方式。
比如我们经常用 pwd
获取当前目录的路径,ls
获取当前目录下的文件,下面是通过 spawnSync
调用示例。
```js import ChildProcess from 'child_process'
const { spawn, spawnSync } = ChildProcess
const pwd = spawnSync('pwd') console.log(pwd.stdout.toString()) const ls = spawnSync('ls', ['-lh']) console.log(ls.stdout.toString()) ```
通过 Git 获取某个文件最近一次的改动时间,
sh
git log -1 --pretty="%ci" ../fs/index.mjs
下面是 spawn
实现。
```js import ChildProcess from 'child_process'
const { spawn, spawnSync } = ChildProcess
const file = './../fs/index.mjs'
const spawnProcess = spawn('git', ['log', '-1', '--pretty="%ci"', file])
spawnProcess.stdout.on('data', (data) => {
console.log(stdout: ${data}
)
console.log(new Date(data))
})
```
有时候我们就想直接执行,让它按照之前的方式正常打印 log 和交互,不需要内部处理。
可以设置 stdio:'inherit'
,表示将子进程的标准输入/输出/错误流与父进程共享。
```js spawnSync('pwd', { stdio: 'inherit' })
spawn('ls', { stdio: 'inherit' }) ```
同样的也是支持同步和异步两种 exec
,execSync
,
简单的实现一下上面的例子。
```js import { exec, execSync } from 'child_process'
const pwd = execSync('pwd') console.log(pwd.toString()) const ls = execSync('ls -lh') console.log(ls.toString())
const file = './../fs/index.mjs'
const execProcess = exec(git log -1 --pretty="%ci" ${file}
)
execProcess.stdout.on('data', (data) => {
console.log(stdout: ${data}
)
console.log(new Date(data))
})
```
执行某个可执行文件,支持同步和异步两种方式,
我们先编写一个可执行文件 hello
,代码内容如下。
```js
const hello = 'hello world' console.log(hello) console.log(process.env) ```
通过 execFile
调用执行。
```js import { execFile, execFileSync } from 'child_process'
const file = './hello' const execData = execFileSync(file) console.log(execData.toString())
execFile(file, (error, stdout, stderr) => { if (error) { throw error } console.log(stdout) console.log(stderr) }) ```
在父进程中,我们可以使用 fork() 方法创建一个子进程,并与子进程进行通信,
下面是具体的例子。
child.mjs
代码如下。
js
process.on('message', (msg) => {
// 监听来自父进程的消息
console.log(`Message from parent: ${msg}`)
process.send('Hello from child!') // 向父进程发送消息
})
fork.mjs
代码如下。
```js import { fork } from 'child_process'
const child = fork('child.mjs') // 使用 fork() 方法创建子进程
child.on('message', (msg) => {
// 监听来自子进程的消息
console.log(Message from child: ${msg}
)
})
child.send('Hello from parent!') // 向子进程发送消息 ```
运行结果如下。
通过 child_process
可以创建子进程实现多任务并行处理,也可通过其调用系统的功能指令完成复杂的任务,
主要介绍了如下 4 个方法的用法和作用。
spawn
启动一个子进程来执行指定的命令,并且可以通过流式数据通信与子进程进行交互;exec
启动一个 shell,并在 shell 中执行指定命令,执行完毕后插入 stdout/stderr
中,适用于一些命令行工具;execFile
与 exec
类似,但是可以直接执行某个文件,而无需通过 shell 执行;fork
专门用于在 Node.js 中衍生新的进程来执行 JavaScript 文件,并且建立一个与子进程的 IPC 通信管道。